A smooth curve can be drawn through a set of points using one of the routines:
gDrawAkimaTo2D(npts, points, beg, fin)Both sets of routines generate a piecewise parametric cubic curve drawn through each pair of points supplied either as absolute or relative coordinates. The first pair (gDrawAkimaTo2D()/ gDrawAkimaBy2D()) use an averaging method due to Akima, which produces a tighter curve, but can be less accurate for (single-valued) functional data. The second pair (gDrawCurveTo2D()/ gDrawCurveBy2D()) produce a looser curve, but is useful for contour drawing. Both sets are very accurate at drawing an approximation to a circle. A comparison of both methods can be seen in a later figure.
By default, the end conditions of a curve are somewhat ill-defined as the undefined slopes may need to be set by additional data. If end point conditions are to be specified then beg and/or fin should be set to GXPOINT or GANGLE, and the end point information given through the routine gSetCurveAttribs2D():
gSetCurveAttribs2D(cbeg, sbeg, cfin, sfin, xbeg, ybeg, xfin, yfin)Similarly, the end conditions following the drawing of a curve may be enquired by using the routine gEnqCurveAttribs2D(), which has the same arguments as gSetCurveAttribs2D(). The values returned in gEnqCurveAttribs2D() will be either those supplied by a previous call to gSetCurveAttribs2D() or those set by the curve drawing routines if no call to gSetCurveAttribs2D() has been made.
Both start and finish angles are made with the positive x-axis, see below.
![]() |
Curve Drawing |
The curve is drawn using straight line segments in the same way as software arcs are generated. As with arcs, the smoothness of the curve can be varied using GSetArcIncrement()/ gSetArcTolerance(). Due to the nature of the different algorithms GSetArcIncrement() controls the number of increments on the Akima curves and gSetArcTolerance() controls the tolerance of the standard curve.
In all the following examples of curve drawings, the same set of data points is used, and is set up as follows:
[C/C++] static GPOINT pt[6] =
   {3.0,3.0, 3.0,6.0,
    6.0,6.0, 4.5,4.5,
    7.0,2.0, 12.0,4.0};
[F90] type (GPOINT) :: pt(6) = (/&
   GPOINT{3.,3.),GPOINT{3.,6.), &
   GPOINT{6.,6.),GPOINT{4.5,4.5), &
   GPOINT{7.,2.),GPOINT{12.,4.} /)
The data points are shown on the curves as asterisks. This is done by using the following call in each case:
call gDrawPolymarkerTo2D(6,pt,8)
[C/C++] gDrawAkimaTo2D(6,pt,GNONE,GNONE);
gDrawCurveTo2D(6,pt,GNONE,GNONE);
[F90] call gDrawAkimaTo2D(6,pt,GNONE,GNONE)
call gDrawCurveTo2D(6,pt,GNONE,GNONE)
![]() |
Akima and Curve (dashed) comparison |
[C/C++] alpha = 45.0 *3.142/180.0;
cosbeg = cos(alpha);
sinbeg = sin(alpha);
gSetCurveAttribs(cosbeg,sinbeg,0.0,0.0,0.0,0.0,0.0,0.0);
gDrawCurveTo2D(6,pt,GANGLE,GNONE);
[F90] alpha = 45.0 *3.142/180.0
cosbeg = cos(alpha)
sinbeg = sin(alpha)
call gSetCurveAttribs(cosbeg,sinbeg,0.0,0.0,0.0,0.0,0.0,0.0)
call gDrawCurveTo2D(6,pt,GANGLE,GNONE)
![]() |
curve with Beginning Conditions of COS and SIN |
[C/C++] xf = 9.0;
yf = 7.0;
gSetCurveAttribs(0.0,0.0,0.0,0.0,0.0,0.0,xf,yf);
gDrawCurveTo2D(6,pt,GNONE,GXPOINT);
[F90] xf = 9.0
yf = 7.0
call gSetCurveAttribs(0.0,0.0,0.0,0.0,0.0,0.0,xf,yf)
call gDrawCurveTo2D(6,pt,GNONE,GXPOINT)
![]() |
End Conditions Specified by Extra Point |
[C/C++] /*  ANGLE = 180 degrees */
alpha = 3.142;
cosfin = cos(alpha);
sinfin = sin(alpha);
xb = 3.0;
yb = 4.0;
gSetCurveAttribs(0.0,0.0,cosfin,sinfin,xb,yb,0.0,0.0);
gDrawCurveTo2D(6,pt,GXPOINT,GANGLE);
[F90] !  ANGLE = 180 degrees
alpha = 3.142
cosfin = cos(alpha)
sinfin = sin(alpha)
xb = 3.0
yb = 4.0
call gSetCurveAttribs(0.0,0.0,cosfin,sinfin,xb,yb,0.0,0.0)
call gDrawCurveTo2D(6,pt,GXPOINT,GANGLE)
![]() |
Example with Both Ends Specified |
![]() |
Curves with no and both ends specified |
Note that gDrawCurveBy2D() uses the values in the points array as relative points, so data points in the previous example would become:
[C/C++] static GPOINT pt[6] = {
   0.0,0.0,   0.0,3.0,
   3.0,0.0,  -1.5,-1.5,
   2.5,-2.5,  5.0,2.0};
[F90] type (GPOINT) :: pt(6) = (/&
   GPOINT(0.,0.),GPOINT(0., 3.),&
   GPOINT{3.,0.),GPOINT(-1.5,-1.5),&
   GPOINT(2.5,-2.5),GPOINT(5.,2.} /)
Note also that gDrawCurveTo2D() does an absolute move to the first X,Y coordinate pair, whereas gDrawCurveBy2D() uses the current position as the first X,Y coordinate pair.